/* ----------------------------------------------------------------------------
 * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved.
 * Description: LiteOS Task Module Implementation
 * Author: wangmihu
 * Create: 2015-01-01
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific prior written
 * permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------------
 * Notice of Export Control Law
 * ===============================================
 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
 * applicable export control laws and regulations.
 * --------------------------------------------------------------------------- */
#ifndef _BCACHE_H
#define _BCACHE_H

#include "linux/rbtree.h"
#include "los_list.h"
#include "pthread.h"

#ifdef LOSCFG_SHELL
#include "reset_shell.h"
#endif

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */

#define ALIGN_LIB(x) ((x + (HALARC_ALIGNMENT - 1)) & ~(HALARC_ALIGNMENT - 1))
#define ALIGN_DISP(x) (HALARC_ALIGNMENT - (x & (HALARC_ALIGNMENT - 1)))
#define BLIB_PREREAD_PRIO 12

typedef int (*BcacheReadFun)(VOID *,  // private data
                             VOID *,  // block buffer
                             UINT32 *,  // number of blocks to read
                             UINT64);  // starting block number

typedef int (*BcacheWriteFun)(VOID *,  // private data
                              const VOID *,  // block buffer
                              UINT32 *,  // number of blocks to write
                              UINT64);  // starting block number

typedef VOID (*BcachePrereadFun)(VOID *,  // block cache instance space holder
                                 VOID *);  // block data

typedef struct {
    VOID *priv;  // private data
    LOS_DL_LIST listHead;  // head of block list
    struct rb_root rbRoot;  // block red-black tree root
    UINT32 blockSize;  // block size in bytes
    UINT32 blockSizeLog2;  // block size log2
    UINT32 blockCount;  // block count of the disk
    UINT32 sectorSize;  // device sector size in bytes
    UINT32 sectorPerBlock;  // device sector size in bytes
    UINT8 *memStart;  // memory base
    UINT32 prereadTaskId;  // preread task id
    UINT32 curBlockNum;  // current preread block number
    LOS_DL_LIST freeListHead;  // list of free blocks
    BcacheReadFun breadFun;  // block read function
    BcacheWriteFun bwriteFun;  // block write function
    BcachePrereadFun prereadFun;  // block preread function
    UINT8 *rwBuffer;  // buffer for bcache block
    pthread_mutex_t bcacheMutex;  // mutex for bcache
    EVENT_CB_S bcacheEvent;  // event for bcache
    UINT32 modifiedBlock; // number of modified blocks
    UINT32 syncTaskId; // sync task id
} OsBcache;

typedef VOID *OsIoHandle;

/**********************************************************************
* Reads data
*
*   bc   - block cache instance
*   buf  - data buffer ptr
*   len  - number of bytes to read
*   bnum - starting block number
*   pos  - starting position inside starting block
*
*   returns ENOERR if read succeded
*
*   The block number is automatically adjusted if
*   position is greater than block size
************************************************************************/
INT32 BlockCacheRead(OsBcache *bc,
                     VOID *buf,
                     UINT32 *len,
                     UINT32 bnum,
                     UINT64 pos);

/**********************************************************************
* Writes data
*
*   bc   - block cache instance
*   buf  - data buffer ptr
*   len  - number of bytes to write
*   bnum - starting block number
*   pos  - starting position inside starting block
*
*   returns ENOERR if write succeded
*
*   The block number is automatically adjusted if
*   position is greater than block size
************************************************************************/
INT32 BlockCacheWrite(OsBcache *bc,
                      const VOID *buf,
                      UINT32 *len,
                      UINT32 bnum,
                      UINT64 pos);

/**********************************************************************
* Syncs block cache - write modified blocks
*
*   bc - block lib instance
*
*   returns ENOERR if sync succeded
************************************************************************/
int BlockCacheSync(OsBcache *bc);

/**********************************************************************
* Init cache
*
*   devNode   - device node
*   sectorSize  - sector size
*   sectorPerBlock  - sectors of per block
*   blockNum - block number
*   blockCount  - block counts
*
*   returns OsBcache pointer if init succeded
*
************************************************************************/
OsBcache *BlockCacheInit(VOID *devNode,
                         UINT32 sectorSize,
                         UINT32 sectorPerBlock,
                         UINT32 blockNum,
                         UINT32 blockCount);

/**********************************************************************
* Deinit cache
*
*   bc   - block cache instance
*
************************************************************************/
VOID BlockCacheDeinit(OsBcache *bc);

VOID BcacheSyncThreadInit(OsBcache *bc, INT32 id);
VOID BcacheSyncThreadDeinit(OsBcache *bc);

UINT32 BcacheAsyncPrereadInit(OsBcache *bc);
VOID ResumeAsyncPreread(VOID *arg1, VOID *arg2);
UINT32 BcacheAsyncPrereadDeinit(OsBcache *bc);

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif  // VFSONCE_BCACHE_H

